var browser = {
	versions: function () {
		var u = navigator.userAgent, app = navigator.appVersion;
		return {// 移动终端浏览器版本信息
			trident: u.indexOf('Trident') > -1, // IE内核
			nokia: u.toUpperCase().indexOf("NOKI") > -1, // nokia
			symbian: u.toUpperCase().indexOf("SYMBIAN") > -1, // symbian
			presto: u.indexOf('Presto') > -1, // opera内核
			webKit: u.indexOf('AppleWebKit') > -1, // 苹果、谷歌内核
			gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, // 火狐内核
			mobile: !!u.match(/AppleWebKit.*Mobile.*/) || !!u.match(/Mobile/), // 是否为移动终端||!!u.match(/AppleWebKit/)
			ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios终端
			linux: u.indexOf('Linux') > -1,
			android: u.indexOf('Android') > -1, // android终端或者uc浏览器
			iPhone: u.indexOf('iPhone') > -1 || u.indexOf('Mac') > -1, // 是否为iPhone或者QQHD浏览器
			iPad: u.indexOf('iPad') > -1, // 是否iPad
			surface: u.indexOf('Trident') > -1 && u.indexOf('Touch') > -1 && u.indexOf('Tablet PC') > -1, // 是否surface
			webApp: u.indexOf('Safari') == -1
			// 是否web应该程序，没有头部与底部
		};
	}(),
	language: (navigator.browserLanguage || navigator.language).toLowerCase()
};
var bridge = {
	default: this,// for typescript
	call: function (method, args, cb) {
		var ret = '';
		if (typeof args == 'function') {
			cb = args;
			args = {};
		}
		var arg = { data: args === undefined ? null : args }
		if (typeof cb == 'function') {
			var cbName = 'dscb' + window.dscb++;
			window[cbName] = cb;
			arg['_dscbstub'] = cbName;
		}
		arg = JSON.stringify(arg)

		//if in webview that dsBridge provided, call!
		if (window._dsbridge) {
			ret = _dsbridge.call(method, arg)
		} else if (window._dswk || navigator.userAgent.indexOf("_dsbridge") != -1) {
			ret = prompt("_dsbridge=" + method, arg);
		}

		return JSON.parse(ret || '{}').data
	},
	register: function (name, fun, asyn) {
		var q = asyn ? window._dsaf : window._dsf
		if (!window._dsInit) {
			window._dsInit = true;
			//notify native that js apis register successfully on next event loop
			setTimeout(function () {
				bridge.call("_dsb.dsinit");
			}, 0)
		}
		if (typeof fun == "object") {
			q._obs[name] = fun;
		} else {
			q[name] = fun
		}
	},
	registerAsyn: function (name, fun) {
		this.register(name, fun, true);
	},
	hasNativeMethod: function (name, type) {
		return this.call("_dsb.hasNativeMethod", { name: name, type: type || "all" });
	},
	disableJavascriptDialogBlock: function (disable) {
		this.call("_dsb.disableJavascriptDialogBlock", {
			disable: disable !== false
		})
	}
};

var awsJSApi = {
	//getDeviceId({callback:function (v){}});
	getDeviceId: function (args) {
		dsBridge.call("getDeviceId", args.callback);
	},
	//addEventListener({eventName:"eventName",callback:function (v){}});
	addEventListener: function (args) {
		dsBridge.call("addAWSEventListener", args, args.callback);
	},
	//setCanGoback({canGoback:true});
	setCanGoback: function (args) {
		dsBridge.call("setWebViewBack", args);
	},
	//getNFCContent({callback:function (v){}});
	getNFCContent: function (args) {
		dsBridge.call("getNFCContent", args.callback);
	},
	//setNFCContent({id:"id",content:"content",callback:function (v){}});
	setNFCContent: function (args) {
		dsBridge.call("setNFCContent", args, args.callback);
	},
	//		editDoc: function (downloadUrl, uploadUrl, saveJson, saveFunc, openType, openRevision) {
	//			if (browser.versions.mobile && (navigator.userAgent.indexOf('iPhone') > -1 || navigator.userAgent.indexOf('iPad') > -1)) {
	//				window.webkit.messageHandlers.editDoc.postMessage([downloadUrl, uploadUrl, saveJson, saveFunc, openType, openRevision]);
	//			} else if (browser.versions.mobile && browser.versions.android) {
	//				webview.editDoc(downloadUrl, uploadUrl, saveJson, saveFunc, openType, openRevision);
	//			}
	//		},
	closeCurrentWebview: function () {
		try {
			dsBridge.call("closeWebview");
		} catch (e) {
		}
	},
	resetPwd: function () {
    		try {
    			dsBridge.call("resetPwd");
    		} catch (e) {
    		}
    	},
    	logout: function () {
            		try {
            			dsBridge.call("logout");
            		} catch (e) {
            		}
            	},
            	exitApp: function () {
                            		try {
                            			dsBridge.call("exitApp");
                            		} catch (e) {
                            		}
                            	},
	chooseImage: function (args) {
		dsBridge.call("chooseImage", args, function (v) {
			var data = JSON.parse(v);
			if (data.result == "ok") {
				args.success(data);
			} else {
				args.fail(data);
			}
		});
	},
	//		uploadPhoto: function (params) {
	//			if (browser.versions.mobile && (navigator.userAgent.indexOf('iPhone') > -1 || navigator.userAgent.indexOf('iPad') > -1)) {
	//				window.webkit.messageHandlers.uploadPhoto.postMessage(JSON.stringify(params));
	//			} else if (browser.versions.mobile && browser.versions.android) {
	//				webview.uploadPhoto(JSON.stringify(params));
	//			}
	//		},
	openProcessCenter: function () {
		if (browser.versions.mobile && (navigator.userAgent.indexOf('iPhone') > -1 || navigator.userAgent.indexOf('iPad') > -1)) {
			this.openApp({ appId: "com.actionsoft.apps.processcenter.ios" });
		} else if (browser.versions.mobile && browser.versions.android) {
			this.openApp({ appId: "com.actionsoft.apps.processcenter.android" });
		}
	},
	openCanledar: function () {
		if (browser.versions.mobile && (navigator.userAgent.indexOf('iPhone') > -1 || navigator.userAgent.indexOf('iPad') > -1)) {
			this.openApp({ appId: "com.actionsoft.apps.calendar.ios" });
		} else if (browser.versions.mobile && browser.versions.android) {
			this.openApp({ appId: "com.actionsoft.apps.calendar.android" });
		}
	},
	openApp: function (args) {
		dsBridge.call("openApp", args);
	},
	openCanledarDetail: function (args) {
		if (browser.versions.mobile && (navigator.userAgent.indexOf('iPhone') > -1 || navigator.userAgent.indexOf('iPad') > -1)) {
			var detail = 'com.actionsoft.apps.calendar.ios://scheduleId=' + args.scheduleId;
			dsBridge.call("openAppDetail", { detail: detail });
		} else if (browser.versions.mobile && browser.versions.android) {
			var detail = 'com.actionsoft.apps.calendar.android:scheduleId=' + args.scheduleId
			dsBridge.call("openAppDetail", { detail: detail });
		}
	},
	//setTitle({title:"title"});

	setOrientation: function (args) {
		dsBridge.call("setOrientation", args);
	},

	setTitle: function (args) {
		dsBridge.call("setTitle", args);
	},

	isRegisterFace: function (args) {
		dsBridge.call("isRegisterFace", args.callback);
	},

	registerFace: function (args) {
		dsBridge.call("registerFace", args, function (v) {
			var data = JSON.parse(v);
			if (data.result == "ok") {
				args.success(data);
			} else {
				args.fail(data);
			}
		});
	},

	verifyFace: function (args) {
		dsBridge.call("verifyFace", args, function (v) {
			var data = JSON.parse(v);
			if (data.result == "ok") {
				args.success(data);
			} else {
				args.fail(data);
			}
		});
	},

	//setTitleColor({backgroundColor:"backgroundColor",titleColor:"titleColor",backButtonColor:"backButtonColor",closeButtonColor:"closeButtonColor"});
	setTitleColor: function (args) {
		dsBridge.call("setTitleColor", args);
	},
	hideTitle: function () {
		dsBridge.call("hideTitle");
	},
	showTitle: function () {
		dsBridge.call("showTitle");
	},
	hideMenu: function () {
		dsBridge.call("hideMenu");
	},
	showMenu: function () {
		dsBridge.call("showMenu");
	},
	sessionTimeout: function () {
		dsBridge.call("sessionTimeout");
	},
	//openWebview({url:"url",canGoback:true,params:params});
	openWebviewPost: function (args) {
		if (args.canGoback == undefined) {
			args.canGoback = false;
		}
		if (args.params != undefined && args.params != null) {
			var paramstring = this.jsonToUrlStr(args.params);
			args.params = paramstring;
		}

		dsBridge.call("openWebviewPost", args);
	},
	//openWebview({url:"url",canGoback:true});
	openWebview: function (args) {// 当无法执行时，放回false，让外层处理
		if (args.canGoback == undefined) {
			args.canGoback = false;
		}
		dsBridge.call("openWebview", args);
	},

	setFaceMd5: function (args) {
		dsBridge.call("setFaceMd5", args);
	},

	jsonToUrlStr: function (json) {
		var urlStr = "";
		var i = 0;
		for (var key in json) {
			if (i != 0) {
				urlStr += "&";
			}
			urlStr += key + "=" + json[key];
			i++;
		}
		return urlStr;
	},
	//executeJsInPreviousWebview({code:"code",callback:function (v){}})
	executeJsInPreviousWebview: function (args) {
		dsBridge.call("executeJsInPreviousWebview", args, args.callback);
	},
	isMobileAWSApp: function () {
		// 判断是否是手机app移动门户
		if (browser.versions.mobile && (navigator.userAgent.indexOf('iPhone') > -1 || navigator.userAgent.indexOf('iPad') > -1)) {
			if (window.webkit.messageHandlers.openWebview.postMessage) {
				return "iosApp";
			}
		} else if (browser.versions.mobile && browser.versions.android) {
			if (webview.openWebview) {
				return "androidApp";
			}
		} else {
			return false;
		}
		return false;
	},
	backRefresh: function () {
		dsBridge.call("backRefresh");
	},
	alertDialog: function (args) {
		dsBridge.call("alertDialog", args, function (v) {
			var data = JSON.parse(v);
			if (data.result == "ok") {
				args.success(data);
			} else {
				args.fail(data);
			}
		});
	},
	confirm: function (args) {
		dsBridge.call("confirm", args, function (v) {
			var data = JSON.parse(v);
			if (data.result == "ok") {
				args.success(data);
			} else {
				args.fail(data);
			}
		});
	},
	actionSheet: function (args) {
		dsBridge.call("actionSheet", args, function (v) {
			var data = JSON.parse(v);
			if (data.result == "ok") {
				args.success(data);
			} else {
				args.fail(data);
			}
		});
	}, showPreloader: function (args) {
		dsBridge.call("showPreloader", args, function (v) {
			var data = JSON.parse(v);
			if (data.result == "ok") {
				args.success(data);
			} else {
				args.fail(data);
			}
		});
	},
	hidePreloader: function (args) {
		dsBridge.call("hidePreloader", args, function (v) {
			var data = JSON.parse(v);
			if (data.result == "ok") {
				args.success(data);
			} else {
				args.fail(data);
			}
		});
	},
   	toast: function (args) {
     	dsBridge.call("toast", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },
   	datetimepicker: function (args) {
     	dsBridge.call("datetimepicker", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },
   	datepicker: function (args) {
     	dsBridge.call("datepicker", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },
timepicker: function (args) {
     	dsBridge.call("timepicker", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },

multiSelect: function (args) {
     	dsBridge.call("multiSelect", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },

vibrate: function (args) {
     	dsBridge.call("vibrate", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },

getNetworkType: function (args) {
     	dsBridge.call("getNetworkType", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },

getWifiStatus: function (args) {
     	dsBridge.call("getWifiStatus", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },

getInterface: function (args) {
     	dsBridge.call("getInterface", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },


getPhoneInfo: function (args) {
     	dsBridge.call("getPhoneInfo", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },

extendModal: function (args) {
     	dsBridge.call("extendModal", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },

modal: function (args) {
     	dsBridge.call("modal", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },

pullToRefreshEnable: function (args) {
     	dsBridge.call("pullToRefreshEnable", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },

pullToRefreshDisable: function (args) {
     	dsBridge.call("pullToRefreshDisable", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },

pullToRefreshStop: function (args) {
     	dsBridge.call("pullToRefreshStop", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },

setProgressBarColors: function (args) {
     	dsBridge.call("setProgressBarColors", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },
goBack: function (args) {
     	dsBridge.call("goBack", args, function (v) {
     			var data = JSON.parse(v);
     			if (data.result == "ok") {
     				args.success(data);
     			} else {
     				args.fail(data);
     			}
     		});
    },
replace: function (args) {
      	dsBridge.call("replace", args, function (v) {
      			var data = JSON.parse(v);
      			if (data.result == "ok") {
      				args.success(data);
      			} else {
      				args.fail(data);
      			}
      		});
     },
previewImage: function (args) {
            	dsBridge.call("previewImage", args, function (v) {
            			var data = JSON.parse(v);
            			if (data.result == "ok") {
            				args.success(data);
            			} else {
            				args.fail(data);
            			}
            		});
           },   
scan: function (args) {
            	dsBridge.call("scan", args, function (v) {
            			var data = JSON.parse(v);
            			if (data.result == "ok") {
            				args.success(data);
            			} else {
            				args.fail(data);
            			}
            		});
           }, 
contactComplexPicker: function (args) {
            	dsBridge.call("contactComplexPicker", args, function (v) {
            			var data = JSON.parse(v);
            			if (data.result == "ok") {
            				args.success(data);
            			} else {
            				args.fail(data);
            			}
            		});
           }

};


!function () {
	if (window._dsf) return;
	var _close = window.close;
	var ob = {
		//保存JS同步方法
		_dsf: {
			_obs: {}
		},
		//保存JS异步方法
		_dsaf: {
			_obs: {}
		},
		dscb: 0,
		dsBridge: bridge,
		close: function () {
			if (bridge.hasNativeMethod('_dsb.closePage')) {
				bridge.call("_dsb.closePage")
			} else {
				_close.call(window)
			}
		},
		_handleMessageFromNative: function (info) {
			var arg = JSON.parse(info.data);
			var ret = {
				id: info.callbackId,
				complete: true
			}
			var f = this._dsf[info.method];
			var af = this._dsaf[info.method]
			var callSyn = function (f, ob) {
				ret.data = f.apply(ob, arg)
				bridge.call("_dsb.returnValue", ret)
			}
			var callAsyn = function (f, ob) {
				arg.push(function (data, complete) {
					ret.data = data;
					ret.complete = complete !== false;
					bridge.call("_dsb.returnValue", ret)
				})
				f.apply(ob, arg)
			}
			if (f) {
				callSyn(f, this._dsf);
			} else if (af) {
				callAsyn(af, this._dsaf);
			} else {
				//with namespace
				var name = info.method.split('.');
				if (name.length < 2) return;
				var method = name.pop();
				var namespace = name.join('.')
				var obs = this._dsf._obs;
				var ob = obs[namespace] || {};
				var m = ob[method];
				if (m && typeof m == "function") {
					callSyn(m, ob);
					return;
				}
				obs = this._dsaf._obs;
				ob = obs[namespace] || {};
				m = ob[method];
				if (m && typeof m == "function") {
					callAsyn(m, ob);
					return;
				}
			}
		}
	}
	for (var attr in ob) {
		window[attr] = ob[attr]
	}
	bridge.register("_hasJavascriptMethod", function (method, tag) {
		var name = method.split('.')
		if (name.length < 2) {
			return !!(_dsf[name] || _dsaf[name])
		} else {
			// with namespace
			var method = name.pop()
			var namespace = name.join('.')
			var ob = _dsf._obs[namespace] || _dsaf._obs[namespace]
			return ob && !!ob[method]
		}
	})
}();

//module.exports = bridge;

